def set_stage():
""" Sets up the stage for the game """
stage.set_background("soccerfield")
stage.disable_floor()
def add_player():
""" Adds a player to the stage for the user to control """
player = codesters.Sprite("player1")
player.go_to(0, -180)
player.set_size(0.75)
return player
def add_ball():
""" Adds a ball to the stage and sets its attributes """
ball = codesters.Sprite("soccerball")
ball.set_y_speed(-8)
def head_ball(sprite, hit_sprite):
""" Detects collisions between the player and ball """
my_var = hit_sprite.get_y_speed()
hit_sprite.set_y_speed(-my_var + 1)
my_var = hit_sprite.get_x_speed()
hit_sprite.set_x_speed(my_var + 1)
def main():
""" Sets up the program and calls other functions """
set_stage()
player = add_player()
add_ball()
player.event_collision(head_ball)
main()
t = codesters.Teacher()
defs = t.find_block("def")
move_lefts = t.find_function("move_left")
docstrings = t.find_text('"""')
num_docstrings = len(docstrings)
test_strings = ['move', 'left'] #Adds a player to the stage for the user to control
ignore_defs = ['set_stage', 'main', 'add_player', 'add_ball', 'head_ball']
def get_above_def(line_number, def_list):
""" Returns the name of the nearest function and the distance above the given line number """
function_name = ""
distance = line_number - def_list[0][0]
for func in def_list:
if line_number - func[0] <= distance and line_number - func[0] > 0:
function_name = func[1]
distance = line_number - func[0]
return function_name, distance
def find_new_function(ignore_list, def_list):
""" Returns tuples of (line_number, function def) for any functions that aren't specified in ignore list """
return_list = []
for d in def_list:
count = 0
for i in ignore_list:
if i in d[1]:
break
else:
count += 1
if count == len(ignore_list):
return_list.append((d[0],d[1]))
return return_list
try:
new_functions = find_new_function(ignore_defs, defs)
def_name = new_functions[0][1]
except:
def_name = "DNE"
try:
function_above, def_distance = get_above_def(new_functions[0][0], defs)
except:
function_above = "DNE"
def_distance = "DNE"
try:
def_indent = t.get_indent_at_line(new_functions[0][0])
except:
def_indent = "DNE"
try:
text = docstrings[4][1]
text = text.replace(' ','').lower()
except:
text = "DNE"
# Determine if the text is valid
valid_text = False
for word in test_strings:
if word not in text:
valid_text = False
break
else:
valid_text = True
# Get line number and indent at valid docstring
if valid_text == True:
line_number = docstrings[4][0]
indent = t.get_indent_at_line(line_number)
else:
line_number = "DNE"
indent = "DNE"
try:
def_over_doc, distance = get_above_def(docstrings[4][0], defs)
except:
def_over_doc = "DNE"
distance = "DNE"
try:
tval1 = move_lefts[0][1]
tval1_line_num = move_lefts[0][0]
tval1_indent = t.get_indent_at_line(tval1_line_num)
except:
tval1 = "DNE"
tva11_line_num = "DNE"
tval1_indent = "DNE"
try:
tval1_def, tval1_distance = get_above_def(tval1_line_num, defs)
except:
tval1_def = "DNE"
tval1_distance = "DNE"
t1 = TestObjective()
t1.add_success("move_left" in def_name and "sprite" in def_name, "Great job!")
t1.add_failure(def_name == "DNE", "Did you add Define Function with Parameter?")
t1.add_failure("move_left" not in def_name and def_name != "DNE", "Did you rename the function to move_left()?")
t1.add_failure(def_name != "DNE" and "sprite" not in def_name, "Did you change the parameter of move_left() to sprite?")
t2 = TestObjective()
t2.add_success("head_ball" in function_above, "Great job!")
t2.add_failure("head_ball" not in function_above, "Did you place your new function under head_ball() and above main()?")
t2.add_failure(function_above == "", "Did you place move_left() below head_ball()?")
t3 = TestObjective()
t3.add_success(def_indent == 0, "Great job!")
t3.add_failure(def_indent > 0, "Make sure not to indent move_left() inside another function!")
t3.add_failure(def_indent == "DNE", "Did you add Define Function with Parameter?")
t4 = TestObjective()
t4.add_success(num_docstrings > 5, "Great job!")
t4.add_failure(num_docstrings == 5, "Did you add a Docstring under move_left()?")
t4.add_failure(num_docstrings < 5, "Oops. Did you delete a docstring?")
t5 = TestObjective()
t5.add_success(valid_text == True, "Great job!")
t5.add_failure(valid_text == False, "Did you change the docstring to describe the function?")
t6 = TestObjective()
t6.add_success(indent == 4, "Great job!")
t6.add_failure(indent < 4, "Did you indent the docstring inside move_left()?")
t6.add_failure(indent > 4, "Oops, did you indent the docstring more than once?")
t6.add_failure(indent == "DNE", "Did you indent the docstring inside move_left()?")
t7 = TestObjective()
t7.add_success("move_left" in def_over_doc and distance < 5, "Great job!")
t7.add_failure("move_left" not in def_over_doc, "Did you place the docstring under add_ball()?")
t7.add_failure(distance >= 5, "Make sure the docstring is at the top of the function!")
t7.add_failure(def_over_doc == "DNE", "Did you delete a docstring?")
t8 = TestObjective()
t8.add_success(tval1 != "DNE", "Great job!")
t8.add_failure(tval1 == "DNE", "Did you add Move Left within the move_left() function?")
t9 = TestObjective()
t9.add_success("move_left" in tval1_def and tval1_indent == 4, "Great job!")
t9.add_failure("move_left" not in tval1_def, "Did you place Move Left within the move_left() function?")
t9.add_failure(tval1_indent < 4 or tval1_indent > 4, "Make sure Move Left is indented one time inside move_left()!")
################################################
# Pass test code
# - set pass_required to True if pass is required
# - include tpass before t1 in the test list
pass_required = False
passes = t.find_text("pass")
num_pass_only = 0
for p in passes:
if p[1].lower().replace(' ','') == "pass":
num_pass_only += 1
tpass = TestObjective()
if not pass_required:
tpass.add_success(num_pass_only == 0, "Great job!")
tpass.add_creative(num_pass_only > 0, "Great job! Feel free to delete pass statements now.")
################################################
tester = TestManager()
tester.add_test_list([tpass, t1, t2, t3, t4, t5, t6, t7, t8, t9])
tester.run_tests()
tester.display_first_feedback()